import json
import os
from typing import Iterator, Optional
from uuid import uuid4

from jobs_agency.basics import JobEssence, JobsStore


class FilesJobsStore(JobsStore):
    def __init__(self, work_dir_path: os.PathLike | str):
        self._work_dir_path = work_dir_path

    def _job_file_path(self, job_id: str) -> str:
        return os.path.join(self._work_dir_path, f'job-{job_id}.json')

    def save_job(self, job_id: Optional[str], job_essence: JobEssence) -> str:
        job_id = job_id or uuid4().hex
        os.makedirs(self._work_dir_path, exist_ok=True)
        with open(self._job_file_path(job_id), 'wt', encoding='utf8') as job_file:
            json.dump(job_essence, job_file)
        return job_id

    def load_job(self, job_id: str) -> JobEssence:
        job_file_path = self._job_file_path(job_id)
        if not os.path.exists(job_file_path):
            raise KeyError(f"No such job with id {job_id}")
        with open(job_file_path, 'rt', encoding='utf8') as fp:
            job_essence = json.load(fp)
        return job_essence

    def remove_job(self, job_id: str):
        job_file_path = self._job_file_path(job_id)
        if os.path.exists(job_file_path):
            os.remove(job_file_path)

    def iter_jobs_id(self) -> Iterator[str]:
        if not os.path.exists(self._work_dir_path):
            return
        for fn in os.listdir(self._work_dir_path):
            if fn.startswith("job-") and fn.endswith(".json"):
                yield fn[4:-5]
